home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / t_os / artemis / artsrc1 / subgrp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-30  |  31.0 KB  |  1,439 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992,1993
  4.  
  5.     subgrp.c
  6.  
  7.     補助グラフィック関数群
  8.  
  9.  
  10. ★描画
  11. *    void    mist(int x,int y,int xlen,int ylen,int col)
  12.     void    aapset(int x, int y, int col, int gray)    //(x,y):16bit fixed-point
  13. *    void    aaline(int x1,int y1,int x2,int y2,int col,pen_t *pen,int gray)
  14. *    void    do_paint(int x,int y)
  15. *    void    psetWithPen(int x,int y,int col,pen_t *pen,bool conc_sw)
  16. *    void    lineWithPen(int x1,int y1,int x2,int y2,int col,pen_t *pen,
  17.                         bool first)
  18. *    void    inverse(int x,int y,int xlen,int ylen)
  19.  
  20. ★特殊描画
  21.     void    plot_mat3(int x, int y, int mat[3][3])
  22.     void    plot_diffuse(int x, int y)
  23.     void    plot_sharp(int x,int y)
  24.     void    plot_sand(int x,int y)
  25.     void    plot_airbrush_start(void)
  26.     void    plot_airbrush(int x,int y)
  27. *    void    plot_pen_func(int x,int y,pen_t *pen, void (*func)(int x,int y))
  28. *    void    plot_pen_diffuse(int x, int y, pen_t *pen)
  29. *    void    plot_pen_sand(int x,int y, pen_t *pen)
  30. *    void    blot_plot(int x, int y, int color, int branch, int depth)
  31. *    void    blot2_plot(int x0, int y0, int color, int branch, int depth)
  32.  
  33. ★描画アルゴリズム
  34. *    void    do_line(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  35. *    void    do_boxline(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  36. *    void    do_boxfill(int x1,int y1,int x2,int y2,
  37.                        void func(int x1,int x2,int y)!)
  38. *    void    do_ellipse(int x,int y,int rx,int ry,void func(int x,int y)!)
  39. *    void    do_ellipsefill(int x,int y,int rx,int ry,
  40.                            void func(int x1,int x2,int y)!)
  41.  
  42. ★各種コマンド
  43.     void    commandPFline_sub(int cmd)
  44. *    void    commandPFline()
  45. *    void    commandPFPset()
  46. *    void    commandBlot()
  47. *    void    commandDiffuse()
  48. *    void    commandSand()
  49. *    void    commandGoshi()
  50. *    void    commandPaint()
  51. *    void    commandFreeTest()
  52.     void    commandPolygon_sub(void    func()!, bool eachbackup)
  53.             // func : (x1,x2,y) の引数で呼び出される
  54. *    void    commandDiffuseArea()
  55. *    void    commandSharp()
  56. *    void    commandSandArea()
  57. *    void    cmd_polygon()
  58.  
  59. ★文字描画
  60.     void    grp_putchar_sub(char *dest, char *src, bool kanji, int col)
  61.     void    grp_putchar(int x, int y, int c, int col, int style)
  62. *    void    ART_putstr_style(int x, int y, char *str, int col, int style)
  63. *    void    ART_putstr(int x, int y, char *str, int col)
  64. *    void    ARTputstr12(int x,int y, char *str, int forecol, int backcol)
  65.  
  66. ★計算
  67. *    int        mixcol(int col1, int col2, int rate, bool rnd)
  68. *    int        my_rand()
  69.  
  70. */
  71.  
  72.  
  73. // アンチエイリアス描画をするかしないか
  74. #define    NO_AA
  75.  
  76. #include <stdio.h>
  77. #include <egb.h>
  78. #include <stdlib.h>
  79. #include <msdos.cf>
  80. #include <fnt.h>
  81. #include <ctype.h>
  82. #include <memory.h>
  83. #include <limits.h>
  84.  
  85. #include "ge.h"
  86. #include "plt16.h"
  87. #include "math2.h"
  88. #include "decimal.h"
  89. #include "imageman.h"
  90. #include "dispman.h"
  91.  
  92. /*--------------------------------------------------------*/
  93. /*                     網目模様の描画                     */
  94. /*--------------------------------------------------------*/
  95.  
  96.  
  97. void mist(int x,int y,int xlen,int ylen,int col)    // 網目模様の描画
  98. {
  99.     int i;
  100.     for (i=0; i<ylen-xlen; i+=2)
  101.         gline(x,y+i,x+xlen-1,y+xlen-1+i,col,DrawNORMAL);
  102.     for ( ; i<ylen; i+=2)
  103.         gline(x,y+i,x+ylen-1-i,y+ylen-1,col,DrawNORMAL);
  104.     for (i=2; i<xlen-ylen; i+=2)
  105.         gline(x+i,y,x+ylen-1+i,y+ylen-1,col,DrawNORMAL);
  106.     for ( ; i<xlen; i+=2)
  107.         gline(x+i,y,x+xlen-1,y+xlen-1-i,col,DrawNORMAL);
  108. }
  109.  
  110.  
  111. void    inverse(int x,int y,int xlen,int ylen)    // 白黒反転
  112. {
  113.     if(DMgetifonepage())
  114.     {
  115.         grboxfill(x,y,xlen,ylen,menu_plt(White),DrawXOR);
  116.     }
  117.     else
  118.     {
  119.         int white = menu_plt(White), black = menu_plt(Black);
  120.         int i,j;
  121.         for(i=0; i<ylen; i++)
  122.         {
  123.             for(j=0; j<xlen; j++)
  124.             {
  125.                 int c = gpoint(x+j,y+i);
  126.                 if (c==white) gpset(x+j,y+i,black,DrawNORMAL);
  127.                 if (c==black) gpset(x+j,y+i,white,DrawNORMAL);
  128.             }
  129.         }
  130.     }
  131. }
  132.  
  133.  
  134. /*--------------------------------------------------------*/
  135. /*              アンチエイリアシング直線描画              */
  136. /*--------------------------------------------------------*/
  137.  
  138.  
  139. #ifndef NO_AA
  140.  
  141. static void aapset(int x, int y, int col, int gray)
  142. // (x,y) : 16bit fixed-point 座標
  143. {
  144.     x = (x+128)>>8;        // 8bit fixed-point へ変換
  145.     y = (y+128)>>8;
  146.     int x1,x2,y1,y2,h1,h2,v1,v2,a11,a12,a21,a22;
  147.     x1 =  x &  0xffffff00;
  148.     x2 = x1 + 0x100;
  149.     y1 =  y &  0xffffff00;
  150.     y2 = y1 + 0x100;
  151.     h1 = x2 - x;
  152.     h2 = x - x1;
  153.     v1 = y2 - y;
  154.     v2 = y - y1;
  155.     a11 = (h1*v1)>>8;
  156.     a12 = (h1*v2)>>8;
  157.     a21 = (h2*v1)>>8;
  158.     a22 = (h2*v2)>>8;
  159.     x1 >>= 8;
  160.     y1 >>= 8;
  161.     x2 >>= 8;
  162.     y2 >>= 8;
  163.     if (a11 > 0)
  164.     {
  165.         if (a11 >= 256)
  166.             gpset(x1,y1,col,DrawNORMAL);
  167.         else
  168.             EIMgraypset(x1,y1,col,a11);
  169.     }
  170.     if (a21 > 0)
  171.     {
  172.         if (a21 >= 256)
  173.             gpset(x2,y1,col,DrawNORMAL);
  174.         else
  175.             EIMgraypset(x2,y1,col,a21);
  176.     }
  177.     if (a12 > 0)
  178.     {
  179.         if (a12 >= 256)
  180.             gpset(x1,y2,col,DrawNORMAL);
  181.         else
  182.             EIMgraypset(x1,y2,col,a12);
  183.     }
  184.     if (a22 > 0)
  185.     {
  186.         if (a22 >= 256)
  187.             gpset(x2,y2,col,DrawNORMAL);
  188.         else
  189.             EIMgraypset(x2,y2,col,a22);
  190.     }
  191. }
  192.  
  193. #endif
  194.  
  195.  
  196. void aaline(int x1, int y1, int x2, int y2, int col, pen_t *pen, int gray)
  197. {
  198. #ifdef NO_AA
  199.     lineWithPen(x1,y1,x2,y2,col,pen,YES);
  200. #else
  201.     int dx,dy,r;
  202.     dx = _abs(x2-x1);
  203.     dy = _abs(y2-y1);
  204.     if (dx==0 && dy==0)
  205.     {
  206.         gpset(x1,y1,col,DrawNORMAL);
  207.         return;
  208.     }
  209.     if (dx < dy)
  210.     {
  211.         r = (dx << 16) / dy;
  212.         if (y1 > y2)
  213.             { swap(y1,y2);  swap(x1,x2); }
  214.         if (x1 > x2)
  215.             r = -r;
  216.         int iy,ix;
  217.         ix = x1<<16;
  218.         for (iy = y1; iy <= y2; iy++,ix+=r)
  219.             aapset(ix,iy<<16,col,256);
  220.     }
  221.     else
  222.     {
  223.         r = (dy << 16) / dx;
  224.         if (x1 > x2)
  225.             { swap(y1,y2);  swap(x1,x2); }
  226.         if (y1 > y2)
  227.             r = -r;
  228.         int iy,ix;
  229.         iy = y1<<16;
  230.         for (ix = x1; ix <= x2; ix++,iy+=r)
  231.             aapset(ix<<16,iy,col,256);
  232.     }
  233. #endif
  234. }
  235.  
  236.  
  237. /*--------------------------------------------------------*/
  238. /*                    ペイントルーチン                    */
  239. /*--------------------------------------------------------*/
  240.  
  241. typedef struct {
  242.     short int  x,y;
  243.     short int  px1,px2,py;
  244.     bool mark;
  245. } STACK;
  246.  
  247. static STACK *check(int px1,int px2,int py,int sx1,int sx2,int sy,int y,int border, STACK *stack, int stacksize, STACK *sp)
  248. // 新しい sp を返す
  249. {
  250.     int x;
  251.     bool in_border;
  252.     if (y<0 || EIMgetysize()<=y)
  253.         return sp;
  254.     in_border = YES;
  255.     for (x=sx1; x<=sx2; x++) {
  256.         if (in_border) {
  257.             if (EIMpoint(x,y)==border) {
  258.                 if (!(y==py&&px1<=x&&x<=px2) && sp+1 < stack+stacksize) {
  259.                     sp++;
  260.                     sp->x = x;
  261.                     sp->y = y;
  262.                     sp->px1 = sx1;
  263.                     sp->px2 = sx2;
  264.                     sp->py = sy;
  265.                     sp->mark = TRUE;
  266.                 }
  267.                 in_border = NO;
  268.             }
  269.         } else {
  270.             if (EIMpoint(x,y) != border)
  271.                 in_border = YES;
  272.         }
  273.     }
  274.     return sp;
  275. }
  276.  
  277. static void delete(int sx1,int sx2,int sy,STACK *oldsp, STACK *stack, STACK *sp)
  278. {
  279.     STACK *p,*q;
  280.     for (p=stack; p<=oldsp; p++) {
  281.         if (p->y == sy && sx1 <= p->x && p->x <= sx2) {
  282.             p->mark = NO;
  283.             for (q = oldsp+1; q<=sp; q++) {
  284.                 if (q->y == p->py && p->px1 <= q->x && q->x <= p->px2)
  285.                     q->mark = FALSE;
  286.             }
  287.         }
  288.     }
  289. }
  290.  
  291. static void _do_paint(int x,int y,int col)
  292. {
  293.     #define STACKSIZE 600
  294.     STACK stack[STACKSIZE];
  295.     STACK *sp;
  296.  
  297.     STACK *oldsp;
  298.     int sx,sx1,sx2,sy;
  299.     int px1,px2,py;
  300.     int border;
  301.     int mix = getmixrate();
  302.     
  303.     border = EIMpoint(x,y);
  304.     sp = stack;
  305.     sp->x = x;
  306.     sp->y = y;
  307.     sp->px1 = 0;
  308.     sp->px2 = 0;
  309.     sp->py = 0;
  310.     sp->mark = YES;
  311.     while (sp >= stack) {
  312.         if (sp->mark) {
  313.             sx = sp->x;
  314.             sy = sp->y;
  315.             px1 = sp->px1;
  316.             px2 = sp->px2;
  317.             py = sp->py;
  318.             short *ip;
  319.             for (sx1=sx,ip=(short*)EIMadrs(sx1,sy);
  320.                  sx1 > 0 && *(ip-1) == border;
  321.                  sx1--,ip--)
  322.                 ;
  323.             for (sx2=sx,ip=(short*)EIMadrs(sx2,sy);
  324.                  sx2 < EIMgetxsize()-1 && *(ip+1) == border;
  325.                  sx2++,ip++)
  326.                 ;
  327.             EIMgrayhline(sx1,sx2,sy,col,mix,NO);
  328.             oldsp = --sp;
  329.             sp=check(px1,px2,py,sx1,sx2,sy,sy+1,border, stack, STACKSIZE, sp);
  330.             sp=check(px1,px2,py,sx1,sx2,sy,sy-1,border, stack, STACKSIZE, sp);
  331.             delete(sx1,sx2,sy,oldsp, stack,sp);
  332.         } else
  333.             sp--;
  334.     }
  335. }
  336.  
  337. void do_paint(int x,int y)
  338. {
  339.     _do_paint(x,y,forecol);
  340. }
  341.  
  342.  
  343. /*--------------------------------------------------------*/
  344. /*                        混色処理                        */
  345. /*--------------------------------------------------------*/
  346.  
  347.  
  348.     /* 新しいrand()が合わなくなったんで自家製に切り換え 1993 3/6 */
  349. int my_rand()    // by 戸田 浩
  350. {
  351.     static unsigned int next = 1 ;
  352.     next = next * 1103515245 + 12345 ;
  353.     return (unsigned int)( next / 65536 ) % 32768 ;
  354. }
  355.  
  356.  
  357. int mixcol(int col1, int col2, int rate, bool rnd)
  358. // rnd : 乱数によりディザリングするかどうかのスイッチ
  359. {
  360.     short int r1,g1,b1, r2,g2,b2;
  361.     if (rate == 0)
  362.         return col1;
  363.     if (rate == 256)
  364.         return col2;
  365.     r1 = (col1 >> 5) & 31;
  366.     g1 = (col1 >> 10) & 31;
  367.     b1 =  col1 & 31;
  368.     r2 = (col2 >> 5) & 31;
  369.     g2 = (col2 >> 10) & 31;
  370.     b2 =  col2 & 31;
  371.     if (!rnd)
  372.     {
  373.         short int nr = 256-rate;
  374.         r1 = ((r1 * nr + r2 * (short int)rate + 128) >> 8);
  375.         g1 = ((g1 * nr + g2 * (short int)rate + 128) >> 8);
  376.         b1 = ((b1 * nr + b2 * (short int)rate + 128) >> 8);
  377.     }
  378.     else
  379.     {
  380. #define    R    ((short int)my_rand() & 255)
  381.         short int nr = 256-rate;
  382.         r1 = ((r1 * nr + r2 * (short int)rate + R) >> 8);
  383.         g1 = ((g1 * nr + g2 * (short int)rate + R) >> 8);
  384.         b1 = ((b1 * nr + b2 * (short int)rate + R) >> 8);
  385. #undef R
  386.     }
  387.     return (g1 << 10) + (r1 << 5) + b1;
  388. }
  389.  
  390.  
  391. /*--------------------------------------------------------*/
  392. /*                      濃淡付きPSET                      */
  393. /*--------------------------------------------------------*/
  394.  
  395.  
  396. void psetWithPen(int x,int y,int col,pen_t *pen,bool conc_sw)
  397. {
  398.     void hdraw(int x0,int y0,int dx,int xlen,int dy, short *graymap)
  399.     {
  400.         EIMgrayhline_map(x0+dx,x0+dx+xlen-1,y0+dy,col,graymap,conc_sw);
  401.     }
  402.     pen_fill(pen, hdraw, x,y,YES);
  403. }
  404.  
  405.  
  406. /*--------------------------------------------------------*/
  407. /*                       ぼかし処理                       */
  408. /*--------------------------------------------------------*/
  409.  
  410.  
  411. static void plot_mat3(int x, int y, int mat[3][3])
  412. {
  413.     if (mode != MODE32K)
  414.         return;
  415.     int max_x, max_y;
  416.     max_x = EIMgetxsize() - 1;
  417.     max_y = EIMgetysize() - 1;
  418.     if (x < 0 || y < 0 || max_x < x || max_y < y)
  419.         return;
  420.     int total[3]; // GRB各要素の強さの合計
  421.     int ix,iy;    // x,y について -1,0,1 と変化する変位
  422.     int ix1,ix2,iy1,iy2;
  423.     total[0] = total[1] = total[2] = 0;
  424.     ix1 = _max(x-1,0    ) - x;
  425.     ix2 = _min(x+1,max_x) - x;
  426.     iy1 = _max(y-1,0    ) - y;
  427.     iy2 = _min(y+1,max_y) - y;
  428.     char *ep0,*ep;  int linsiz;
  429.     ep0 = EIMadrs_back(x+ix1, y+iy1);
  430.     linsiz = EIMgetxbytes();
  431.     for (iy=iy1; iy<=iy2; iy++,ep0+=linsiz)
  432.     {
  433.         ep = ep0;
  434.         for (ix=ix1; ix<=ix2; ix++,ep+=2)
  435.         {
  436.             int c = *(short*)ep;
  437.             int p = mat[iy+1][ix+1];
  438.             total[0] += getG(c) * p;
  439.             total[1] += getR(c) * p;
  440.             total[2] += getB(c) * p;
  441.         }
  442.     }
  443. #define    COL_AVR(a)    ((total[a] + 128) >> 8)
  444.     int t1,t2,t3;
  445.     t1 = _lim(COL_AVR(0),0,31);
  446.     t2 = _lim(COL_AVR(1),0,31);
  447.     t3 = _lim(COL_AVR(2),0,31);
  448.     EIMpset(x, y, GRB(t1,t2,t3), DrawNORMAL);
  449. #undef COL_AVR
  450. }
  451.  
  452.  
  453. static void plot_diffuse(int x, int y)
  454. // 1ドットに対してボカシを実行する
  455. {
  456.     static int mat[3][3] = {{23,23,23},{23,72,23},{23,23,23}};
  457.     plot_mat3(x,y,mat);
  458. }
  459.  
  460.  
  461. static void plot_sharp(int x,int y)
  462. {
  463.     static int mat[3][3] = {{-16,-16,-16},{-16,384,-16},{-16,-16,-16}};
  464.     plot_mat3(x,y,mat);
  465. }
  466.  
  467.  
  468. /*--------------------------------------------------------*/
  469. /*                         砂処理                         */
  470. /*--------------------------------------------------------*/
  471.  
  472.  
  473. static void plot_sand(int x,int y)
  474. {
  475.     int i,c,grb[3];
  476.     c = EIMpoint_back(x,y);
  477.     grb[0]=getG(c), grb[1]=getR(c), grb[2]=getB(c);
  478.     int r;
  479.     r = rand() % 3;
  480.     for (i=0; i<3; i++)
  481.     {
  482.         switch(r)
  483.         {
  484.         case 0:
  485.             if (grb[i] > 0)
  486.                 grb[i]--;
  487.             break;
  488.         case 1:
  489.             if (grb[i] < 31)
  490.                 grb[i]++;
  491.             break;
  492.         }
  493.     }
  494.     c = GRB(grb[0],grb[1],grb[2]);
  495.     EIMpset(x,y,c,DrawNORMAL);
  496. }
  497.  
  498.  
  499. /*--------------------------------------------------------*/
  500. /*             ペン先について任意の処理を行う             */
  501. /*--------------------------------------------------------*/
  502.  
  503.  
  504. static void plot_pen_func(int x, int y, pen_t *pen, void (*func)(int x,int y))
  505. {
  506.     void hline(int x0,int y0,int dx,int xlen,int dy, short *graymap)
  507.     {
  508.         int i;
  509.         for (i=0; i<xlen; i++)
  510.             func(x0+dx+i, y0+dy);
  511.     }
  512.     pen_fill(pen, hline, x,y, YES);
  513. }
  514.  
  515.  
  516. void plot_pen_diffuse(int x, int y, pen_t *pen)
  517. // ペンの形状にあわせた「ボカシ」を実行する
  518. {
  519.     plot_pen_func(x,y,pen,plot_diffuse);
  520. }
  521.  
  522.  
  523. void plot_pen_sand(int x,int y, pen_t *pen)
  524. // ペンの形状にあわせた「ザラザラ化」を実行する
  525. {
  526.     plot_pen_func(x,y,pen,plot_sand);
  527. }
  528.  
  529.  
  530. void lineWithPen(int x1,int y1,int x2,int y2,int col,pen_t *pen,bool first)
  531. // first : 最初の点を描画するかどうか
  532. {
  533.     int xr,yr,r,x,y;
  534.     xr = _abs(x2-x1), yr = _abs(y2-y1);
  535.     if (first)
  536.         psetWithPen(x1,y1,col,pen,YES);
  537.     if (xr==0 && yr==0)
  538.         ;
  539.     else if (xr > yr)
  540.     {
  541.         r = (yr<<16) / xr;
  542.         if (y1 > y2)
  543.             r = -r;
  544.         if (x1 < x2)
  545.         {
  546.             for (x=x1+1,y=(y1<<16)+0x8000+r; x<=x2; x++,y+=r)
  547.                 psetWithPen(x,(y>>16),col,pen,YES);
  548.         }
  549.         else 
  550.         {
  551.             for (x=x1-1,y=(y1<<16)+0x8000+r; x>=x2; x--,y+=r)
  552.                 psetWithPen(x,(y>>16),col,pen,YES);
  553.         }
  554.     }
  555.     else
  556.     {
  557.         r = (xr << 16) / yr;
  558.         if (x1 > x2)
  559.             r = -r;
  560.         if (y1 < y2)
  561.         {
  562.             for (y=y1+1,x=(x1<<16)+0x8000+r; y<=y2; y++,x+=r)
  563.                 psetWithPen((x>>16),y,col,pen,YES);
  564.         }
  565.         else
  566.         {
  567.             for (y=y1-1,x=(x1<<16)+0x8000+r; y>=y2; y--,x+=r)
  568.                 psetWithPen((x>>16),y,col,pen,YES);
  569.         }
  570.     }
  571. }
  572.  
  573.  
  574. /*--------------------------------------------------------*/
  575. /*                  「にじみペン」手続き                  */
  576. /*--------------------------------------------------------*/
  577.  
  578. #define    BLOT_METHOD        1
  579.     // 0=従来どおり(画面上で混色)  1=編集バッファと混色
  580.  
  581. void blot_plot(int x, int y, int color, int branch, int depth)
  582. // 3万色編集時専用。
  583. // branch : 枝分かれする数
  584. // depth : 何回再帰するか
  585. {
  586.     if (mode != MODE32K || depth <= 0)
  587.         return;
  588.     int mixr,mixr0;
  589.     mixr0 = getmixrate();
  590.     int max_x, max_y;
  591.     max_x = EIMgetxsize() - 1;
  592.     max_y = EIMgetysize() - 1;
  593.     void blot_plot_sub(int x, int y, int color, int branch, int depth,
  594.                        deci grad, deci gradsub)
  595.     {
  596.         if (depth <= 0 || grad <= 0 ||
  597.             x < 0 || y < 0 || max_x < x || max_y < y)
  598.         {
  599.             return;
  600.         }
  601.         if (mixr0 == 256)
  602.             EIMgraypset(x,y,color,DeciToInt(grad));
  603.         else
  604.         {
  605.             char *cp;  int conc,t;
  606.             conc = DeciToInt(grad);
  607.             cp = cbuf_adrs(x,y);
  608.             t = cbuf_mix(cbuf2conc(*cp), conc, mixr0);
  609.             *cp = conc2cbuf(t);
  610.             EIMpset(x,y,
  611.                     mixcol(EIMpoint_back(x,y),color,t,NO),
  612.                     DrawNORMAL);
  613.         }
  614.         int b;
  615.         for (b = 0; b < branch; b++)
  616.         {
  617.             int nx,ny;
  618.             nx = x + rand() % 3 - 1;
  619.             ny = y + rand() % 3 - 1;
  620.             blot_plot_sub(nx,ny,color,branch,depth-1,grad-gradsub,gradsub);
  621.         }
  622.     }
  623.     if (mixr0 == 256)
  624.         blot_plot_sub(x,y,color,branch,depth,IntToDeci(50),IntToDeci(50)/depth);
  625.     else
  626.     {
  627.         mixr = mixr0 / 5;
  628.         blot_plot_sub(x,y,color,branch,depth,IntToDeci(mixr),IntToDeci(mixr)/depth);
  629.     }
  630. }
  631.  
  632. /*--------------------------------------------------------*/
  633. /*                   にじみペン part 2                    */
  634. /*--------------------------------------------------------*/
  635.  
  636. void blot2_plot(int x0, int y0, int color, int branch, int depth)
  637. // 3万色編集時専用。
  638. // branch : 枝分かれする数
  639. // depth : 何回再帰するか
  640. {
  641.     static int dxy[][2] = {
  642.         {0,-1},    {1,-1},    {1,0},    {1,1},    {0,1},    {-1,1},    {-1,0},    {-1,-1}
  643.     };
  644.     if (mode != MODE32K || depth <= 0)
  645.         return;
  646.     int mixr,mixr0;
  647.     mixr0 = getmixrate();
  648.     int max_x, max_y;
  649.     max_x = EIMgetxsize() - 1;
  650.     max_y = EIMgetysize() - 1;
  651.     void blot_plot_sub(int x, int y, int color, int branch, int depth,
  652.                        deci grad, deci gradsub, int dir)
  653.     {
  654.         if (depth <= 0 || grad <= 0 ||
  655.             x < 0 || y < 0 || max_x < x || max_y < y)
  656.         {
  657.             return;
  658.         }
  659.         if (mixr0 == 256)
  660.             EIMgraypset(x,y,color,DeciToInt(grad));
  661.         else
  662.         {
  663.             char *cp;  int conc,t;
  664.             conc = DeciToInt(grad);
  665.             cp = cbuf_adrs(x,y);
  666.             t = cbuf_mix(cbuf2conc(*cp), conc, mixr0);
  667.             *cp = conc2cbuf(t);
  668.             EIMpset(x,y,
  669.                     mixcol(EIMpoint_back(x,y),color,t,NO),
  670.                     DrawNORMAL);
  671.         }
  672.         int b;
  673.         for (b = 0; b < branch; b++)
  674.         {
  675.             int d;
  676.             do { d = rand() & 7; } while (d == dir);
  677.             if (dir<0) dir=d;
  678.             blot_plot_sub(x+dxy[d][0],y+dxy[d][1],
  679.                           color, branch, depth-1, grad-gradsub, gradsub, dir);
  680.         }
  681.     }
  682.     if (mixr0 == 256)
  683.         blot_plot_sub(x0,y0,color,branch,depth,IntToDeci(50),IntToDeci(50)/depth,-1);
  684.     else
  685.     {
  686.         mixr = mixr0 / 5;
  687.         blot_plot_sub(x0,y0,color,branch,depth,IntToDeci(mixr),IntToDeci(mixr)/depth,-1);
  688.     }
  689. }
  690.  
  691. // ●エアブラシ
  692.  
  693. // static int ab_r,ab_x,ab_y,ab_c;
  694. static short *airbrush_buf = NULL;
  695.  
  696. static int airbrush_init(void)
  697. {
  698.     if (airbrush_buf != NULL)
  699.         free(airbrush_buf);
  700.     airbrush_buf = calloc(2,(spray_r*2+1)*(spray_r*2+1));
  701.     if (airbrush_buf == NULL)
  702.         return -1;
  703.     int x,y;
  704.     int idx=0;
  705.     for (y=-spray_r; y<=spray_r; y++)
  706.         for(x=-spray_r; x<=spray_r; x++,idx++)
  707.         {
  708.             deci r = ID(x*x+y*y) / (spray_r*spray_r);
  709.             if (r<=ID(1))
  710.             {
  711.                 airbrush_buf[idx] = 32 - DI(32*r);
  712.             }
  713.         }
  714.     return 0;
  715. }
  716.  
  717. static void airbrush_end(void)
  718. {
  719.     free(airbrush_buf);
  720.     airbrush_buf = NULL;
  721. }
  722.  
  723. void plot_airbrush_start(void)
  724. {
  725.     // ab_r=0,ab_c=0;
  726.     // ab_x=ab_y=-1;
  727. }
  728.  
  729. void plot_airbrush(int x, int y)
  730. {
  731.     #if 0
  732.         if(x!=ab_x||y!=ab_y)
  733.         {
  734.             ab_c=0;
  735.             if(ab_x<0) ab_r=0;
  736.             else
  737.             {
  738.                 int rx=abs(x-ab_x),ry=abs(y-ab_y);
  739.                 if(rx<=2&&ry<=2)
  740.                     ab_r=0; /* (ab_r*3)/4; */
  741.                 else
  742.                     ab_r=0;
  743.             }
  744.         }
  745.         ab_x=x,ab_y=y;
  746.     #endif
  747.     int maxx,maxy;
  748.     maxx = EIMgetxsize()-1;
  749.     maxy = EIMgetysize()-1;
  750.     int x1,y1,x2,y2,xl,x0,y0;
  751.     x1 = _max(0, (x0 = x - spray_r));
  752.     y1 = _max(0, (y0 = y - spray_r));
  753.     x2 = _min(maxx, x + spray_r);
  754.     y2 = _min(maxx, y + spray_r);
  755.     xl = spray_r * 2 + 1;
  756.     int i;
  757.     int idx = xl * (y1-y0) + (x1-x0);
  758.     for (i=y1; i<=y2; i++,idx+=xl)
  759.     {
  760.         EIMgrayhline_map(x1,x2,i,forecol,&airbrush_buf[idx],YES);
  761.     }
  762.     #if 0
  763.         void hline(int x1,int x2,int y)
  764.         {
  765.             if(y<0||maxy<y) return;
  766.             x1=_max(x1,0);x2=_min(x2,maxx); if(x1>=x2) return;
  767.             EIMgrayhline(x1,x2,y,forecol,32,YES);
  768.         }
  769.     #endif
  770.     // do_ellipsefill(x,y,ab_r,ab_r,hline);
  771.     // ab_r = _min(ab_r+1,spray_r);
  772. }
  773.  
  774. /*--------------------------------------------------------*/
  775. /*                    描画アルゴリズム                    */
  776. /*--------------------------------------------------------*/
  777.  
  778. void do_line(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  779. {
  780.     int xr,yr,r,x,y;
  781.     xr=abs(x2-x1),yr=abs(y2-y1);
  782.     func(x1,y1);    // 最初の点
  783.     if (xr==0 && yr==0)
  784.         ;
  785.     else if (xr > yr)
  786.     {
  787.         r=(yr<<16)/xr; if(y1>y2) r=-r;
  788.         if (x1 < x2)
  789.             for (x=x1+1,y=(y1<<16)+0x8000+r; x<=x2; x++,y+=r)
  790.                 func(x,(y>>16));
  791.         else 
  792.             for (x=x1-1,y=(y1<<16)+0x8000+r; x>=x2; x--,y+=r)
  793.                 func(x,(y>>16));
  794.     }
  795.     else
  796.     {
  797.         r=(xr<<16)/yr; if(x1>x2) r=-r;
  798.         if (y1 < y2)
  799.             for (y=y1+1,x=(x1<<16)+0x8000+r; y<=y2; y++,x+=r)
  800.                 func((x>>16),y);
  801.         else
  802.             for (y=y1-1,x=(x1<<16)+0x8000+r; y>=y2; y--,x+=r)
  803.                 func((x>>16),y);
  804.     }
  805. }
  806.  
  807. void do_boxline(int x1,int y1,int x2,int y2,void func(int x,int y)!)
  808. {
  809.     int i;
  810.     if (x2<x1) swap(x1,x2);
  811.     if (y2<y1) swap(y1,y2);
  812.     for(i=x1;i<=x2;i++) func(i,y1);
  813.     if(y1<y2)
  814.         for(i=x1;i<=x2;i++) func(i,y2);
  815.     for(i=y1+1;i<y2;i++) func(x1,i);
  816.     if(x1<x2)
  817.         for(i=y1+1;i<y2;i++) func(x2,i);
  818. }
  819.  
  820. void do_boxfill(int x1,int y1,int x2,int y2,void func(int x1,int x2,int y)!)
  821. {
  822.     int i;
  823.     if (x2<x1) swap(x1,x2);
  824.     if (y2<y1) swap(y1,y2);
  825.     for(i=y1;i<=y2;i++) func(x1,x2,i);
  826. }
  827.  
  828. void do_ellipse(int x,int y,int rx,int ry,void func(int x,int y)!)
  829. {
  830. #if 0
  831.     #define    ELLIPSE(RX,RY,X0,Y0,X1,Y1)                            \
  832.         {                                                        \
  833.             int x0=RX,s=x0;                                        \
  834.             int y0=0;                                            \
  835.             int px0=-1,py0=-1,px1=-1,py1=-1;                    \
  836.             while(x0>=y0)                                        \
  837.             {                                                    \
  838.                 int x1=x0*RY/RX;                        \
  839.                 int y1=y0*RY/RX;                        \
  840.                 if(px0!=X0||py1!=Y1)                    \
  841.                 {                                                    \
  842.                     func(x+X0,y+Y1);if(X0!=0)func(x-X0,y+Y1);        \
  843.                     if (Y1!=0)                                        \
  844.                      { func(x+X0,y-Y1);if(X0!=0)func(x-X0,y-Y1); }    \
  845.                 }                                                    \
  846.                 if (py0!=Y0||px1!=X1)                                \
  847.                 {                                                \
  848.                     func(x+Y0,y+X1);if(Y0!=0)func(x-Y0,y+X1);        \
  849.                     if (X1!=0)                                        \
  850.                      { func(x+Y0,y-X1);if(Y0!=0)func(x-Y0,y-X1); }    \
  851.                 }                                                \
  852.                 s-=2*y0+1; if(s<0)s+=2*(x0-1),x0--;                \
  853.                 y0++;                                            \
  854.                 px0=X0,py0=Y0,px1=X1,py1=Y1;                    \
  855.             }                                                    \
  856.         }
  857.     #
  858.     if (rx==0 && ry==0)
  859.         func(x,y);
  860.     else if (rx>ry)
  861.         ELLIPSE(rx,ry,x0,y0,x1,y1)
  862.     else
  863.         ELLIPSE(ry,rx,x1,y1,x0,y0)
  864.     #undef ELLIPSE
  865. #endif
  866.     if (rx==0 && ry==0)
  867.         { func(x,y); return; }
  868.     int px,py,prey;
  869.     int a2,b2;
  870.     int c1,c2;
  871.     int e;
  872.     a2=rx*rx,b2=ry*ry;
  873.     px=0,py=ry;
  874.     c1=4*b2,c2=8*a2;
  875.     e=a2*(1-4*ry);
  876.     while(b2*px<=a2*py)
  877.     {
  878.         func(x+px,y+py); if(px!=0)func(x-px,y+py);
  879.         func(x+px,y-py); if(px!=0)func(x-px,y-py);
  880.         prey=py;
  881.         e+=c1*(2*px+1),px++; if(e>0) e-=c2*py,py--;
  882.     }
  883.     px=rx,py=0;
  884.     c1=4*a2,c2=8*b2;
  885.     e=b2*(1-4*rx);
  886.     while(a2*py<=b2*px && py<prey)
  887.     {
  888.         func(x+px,y+py); if(px!=0)func(x-px,y+py);
  889.         if(py!=0) { func(x+px,y-py); if(px!=0)func(x-px,y-py); }
  890.         e+=c1*(2*py+1),py++; if(e>0) e-=c2*px,px--;
  891.     }
  892. }
  893.  
  894. void do_ellipsefill(int x,int y,int rx,int ry,void func(int x1,int x2,int y)!)
  895. {
  896. #if 0
  897.     #define    ELLIPSE(RX,RY,X0,Y0,X1,Y1)                    \
  898.         {                                                \
  899.             int x0=RX,s=x0;                                \
  900.             int y0=0;                                    \
  901.             int py0,py1;                                \
  902.             py0=py1=INT_MIN;                            \
  903.             while(x0>=y0)                                \
  904.             {                                            \
  905.                 int x1=x0*RY/RX;                        \
  906.                 int y1=y0*RY/RX;                        \
  907.                 if (y+Y1 != py0)                        \
  908.                 {                                        \
  909.                     py0=y+Y1;                            \
  910.                     func(x-X0,x+X0,py0);                \
  911.                     func(x-X0,x+X0,y-Y1);                \
  912.                 }                                        \
  913.                 if (y+X1 != py1)                        \
  914.                 {                                        \
  915.                     py1=y+X1;                            \
  916.                     func(x-Y0,x+Y0,py1);                \
  917.                     func(x-Y0,x+Y0,y-X1);                \
  918.                 }                                        \
  919.                 s-=2*y0-1; if(s<0)s+=2*(x0-1),x0--;        \
  920.                 y0++;                                    \
  921.             }                                            \
  922.         }
  923.     #
  924.     if (rx==0&&ry==0)
  925.         func(x,x,y);
  926.     else if (rx>ry)
  927.         ELLIPSE(rx,ry,x0,y0,x1,y1)
  928.     else
  929.         ELLIPSE(ry,rx,x1,y1,x0,y0)
  930.     #undef ELLIPSE
  931. #endif
  932.     if (rx==0 && ry==0)
  933.         { func(x,x,y); return; }
  934.     int px,py,prey;
  935.     int a2,b2;
  936.     int c1,c2;
  937.     int e;
  938.     a2=rx*rx,b2=ry*ry;
  939.     px=0,py=ry;
  940.     c1=4*b2,c2=8*a2;
  941.     e=a2*(1-4*ry);
  942.     prey=-1;
  943.     while(b2*px<=a2*py)
  944.     {
  945.         e+=c1*(2*px+1);
  946.         if(e>0)
  947.         {
  948.             func(x-px,x+px,y+py); func(x-px,x+px,y-py);
  949.             prey=py;
  950.              e-=c2*py,py--;
  951.         }
  952.         px++;
  953.     }
  954.     px=rx,py=0;
  955.     c1=4*a2,c2=8*b2;
  956.     e=b2*(1-4*rx);
  957.     while(a2*py<=b2*px && py<prey)
  958.     {
  959.         func(x-px,x+px,y+py);
  960.         if(py!=0) func(x-px,x+px,y-py);
  961.         e+=c1*(2*py+1),py++; if(e>0) e-=c2*px,px--;
  962.     }
  963. }
  964.  
  965. /*--------------------------------------------------------*/
  966. /*                   「自由線」コマンド                   */
  967. /*--------------------------------------------------------*/
  968.  
  969.  
  970. extern void put_pencol(), get_pencol();
  971.  
  972.  
  973. static void commandPFline_sub(int cmd)
  974. // cmd 0:fline 1:pset
  975. {
  976.     if (cmd == 8)
  977.     {
  978.         if (airbrush_init() != 0)
  979.             return;
  980.     }
  981.     bool drawing;
  982.     int px,py;
  983.     drawing = NO;
  984.     for (;;)
  985.     {
  986.         DMdispcsr(ms.x,ms.y);
  987.         do
  988.         {
  989.             ms_get(&ms);
  990.         } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  991.                  key_chk() == 0);
  992.         DMerasecsr();
  993.         scrollForCsr(1,1);
  994.         if (ms.btn2==OFFON)
  995.             break;
  996.         else if (ms.btn1==OFFON)
  997.         {
  998.             EIMbackup();
  999.             drawing = YES;
  1000.             px = DMimage_getx(ms.x),  py = DMimage_gety(ms.y);
  1001.             switch (cmd)
  1002.             {
  1003.             case 0:
  1004.             case 1:
  1005.                 cbuf_clear();
  1006.                 psetWithPen(px,py,forecol,getcurpen(),YES);
  1007.                 break;
  1008.             case 2:
  1009.                 cbuf_clear();
  1010.                 blot_plot(px,py,forecol,1,blot_depth);
  1011.                 break;
  1012.             case 3:
  1013.                 plot_pen_diffuse(px,py,getcurpen());
  1014.                 break;
  1015.             case 4:
  1016.                 plot_pen_sand(px,py,getcurpen());
  1017.                 break;
  1018.             case 5:
  1019.                 get_pencol(px,py,getcurpen());
  1020.                 break;
  1021.             case 6:
  1022.                 do_paint(px,py);
  1023.                 break;
  1024.             case 7:    // freetest
  1025.                 cbuf_clear();
  1026.                 blot2_plot(px,py,forecol,1,blot_depth);
  1027.                 break;
  1028.             case 8:
  1029.                 cbuf_clear();
  1030.                 plot_airbrush_start();
  1031.                 plot_airbrush(px,py);
  1032.                 break;
  1033.             }
  1034.         }
  1035.         else if (ms.btn1==ON)
  1036.         {
  1037.             if (drawing)
  1038.             {
  1039.                 int nx,ny;
  1040.                 nx = DMimage_getx(ms.x),  ny = DMimage_gety(ms.y);
  1041.                 switch (cmd)
  1042.                 {
  1043.                 case 0:
  1044.                     if (px!=nx||py!=ny)
  1045.                     {
  1046.                         if (ryosuke && pen_isdottype(getcurpen()))
  1047.                             aaline(px,py,nx,ny,forecol,getcurpen(),256);
  1048.                         else
  1049.                             lineWithPen(px,py,nx,ny,forecol,getcurpen(),NO);
  1050.                     }
  1051.                     break;
  1052.                 case 1:
  1053.                     if (px!=nx||py!=ny)
  1054.                         psetWithPen(nx,ny,forecol,getcurpen(),YES);
  1055.                     break;
  1056.                 case 2:    // にじみペン
  1057.                     blot_plot(nx,ny,forecol,1,blot_depth);
  1058.                     break;
  1059.                 case 3: // ぼかしペン
  1060.                     if (px!=nx||py!=ny)
  1061.                         plot_pen_diffuse(nx,ny,getcurpen());
  1062.                     break;
  1063.                 case 4: // ザラザラペン
  1064.                     if (px!=nx||py!=ny)
  1065.                         plot_pen_sand(nx,ny,getcurpen());
  1066.                     break;
  1067.                 case 5: // 摩筆
  1068.                     if (px!=nx||py!=ny)
  1069.                         put_pencol(nx,ny,getcurpen());
  1070.                     break;
  1071.                 case 7:    // freetest
  1072.                     blot2_plot(px,py,forecol,1,blot_depth);
  1073.                     break;
  1074.                 case 8:
  1075.                     plot_airbrush(px,py);
  1076.                     break;
  1077.                 }
  1078.                 px=nx;
  1079.                 py=ny;
  1080.             }
  1081.         }
  1082.         else
  1083.             drawing = NO;
  1084.     }
  1085.     if (cmd == 8)
  1086.         airbrush_end();
  1087. }
  1088.  
  1089.  
  1090. void commandPFline()
  1091. {
  1092.     commandPFline_sub(0);
  1093. }
  1094.  
  1095.  
  1096. void commandPFPset()
  1097. {
  1098.     commandPFline_sub(1);
  1099. }
  1100.  
  1101.  
  1102. void commandBlot()
  1103. {
  1104.     commandPFline_sub(2);
  1105. }
  1106.  
  1107.  
  1108. void commandDiffuse()
  1109. {
  1110.     commandPFline_sub(3);
  1111. }
  1112.  
  1113.  
  1114. void commandSand()
  1115. {
  1116.     commandPFline_sub(4);
  1117. }
  1118.  
  1119.  
  1120. void commandGoshi()
  1121. {
  1122.     commandPFline_sub(5);
  1123. }
  1124.  
  1125.  
  1126. void commandPaint()
  1127. {
  1128.     commandPFline_sub(6);
  1129. }
  1130.  
  1131.  
  1132. void commandFreeTest()
  1133. {
  1134.     // commandPFline_sub(7); // blot2
  1135.     commandPFline_sub(8); // air-brush
  1136. }
  1137.  
  1138.  
  1139. static void commandPolygon_sub(void func()!, bool eachbackup)
  1140. // func : (x1,x2,y) の引数で呼び出される
  1141. {
  1142.     bool first = YES;
  1143.     for (;;)
  1144.     {
  1145.         if (area_input(AREA_POLYGON) != 0)
  1146.             break;
  1147.         if (eachbackup)
  1148.             EIMbackup();
  1149.         else
  1150.         {
  1151.             if (first)
  1152.                 EIMbackup();
  1153.             first = NO;
  1154.         }
  1155.         int ax1,ay1,ax2,ay2;
  1156.         area_getboundxy(&ax1,&ay1,&ax2,&ay2);
  1157.         int x,y;
  1158.         for (y=ay1; y<=ay2; y++)
  1159.         {
  1160.             x = ax1 + area_chkxylen(ax1,ax2,y,YES);
  1161.             while (x<=ax2)
  1162.             {
  1163.                 int l;
  1164.                 if ((l = area_chkxylen(x,ax2,y,NO)) == 0)
  1165.                     break;
  1166.                 func(x,x+l-1,y);
  1167.                 x += l + area_chkxylen(x+l,ax2,y,YES);
  1168.             }
  1169.         }
  1170.     }
  1171. }
  1172.  
  1173.  
  1174. void commandDiffuseArea()
  1175. {
  1176.     void diffuse_hline(int x1,int x2,int y)
  1177.     {
  1178.         int i;
  1179.         for (i=x1; i<=x2; i++)
  1180.             plot_diffuse(i,y);
  1181.     }
  1182.     commandPolygon_sub(diffuse_hline,YES);
  1183. }
  1184.  
  1185.  
  1186. void commandSharp()
  1187. {
  1188.     void sharp_hline(int x1,int x2,int y)
  1189.     {
  1190.         int i;
  1191.         for (i=x1; i<=x2; i++)
  1192.             plot_sharp(i,y);
  1193.     }
  1194.     commandPolygon_sub(sharp_hline,NO);
  1195. }
  1196.  
  1197.  
  1198. void commandSandArea()
  1199. {
  1200.     void sand_hline(int x1,int x2,int y)
  1201.     {
  1202.         int i;
  1203.         for (i=x1; i<=x2; i++)
  1204.             plot_sand(i,y);
  1205.     }
  1206.     commandPolygon_sub(sand_hline,YES);
  1207. }
  1208.  
  1209.  
  1210. void cmd_polygon()
  1211. {
  1212.     int mix = getmixrate();
  1213.     void hline(int x1,int x2,int y)
  1214.     {
  1215.         EIMgrayhline(x1,x2,y,forecol,mix,NO);
  1216.     }
  1217.     commandPolygon_sub(hline,YES);
  1218. }
  1219.  
  1220.  
  1221. /*--------------------------------------------------------*/
  1222. /*                        文字表示                        */
  1223. /*--------------------------------------------------------*/
  1224.  
  1225.  
  1226. #if 0
  1227. static void grp_putchar_sub(char *dest, char *src, bool kanji, int col)
  1228. /*
  1229.     1 bit pixel 列を 4 bit pixel 列に変換する
  1230. */
  1231. {
  1232.     int i,j;
  1233.     uint col_a[8];
  1234.     static char bit[] = {128,64,32,16,8,4,2,1};
  1235.     col &= 0xf;
  1236.     for (i=0; i<8; i++)
  1237.         col_a[i] = col << (i*4);
  1238.     if (kanji)
  1239.     {
  1240.         for (i=0; i<16; i++,dest+=8,src+=2)
  1241.         {
  1242.             *(uint*)dest = *(uint*)(dest+4) = 0;
  1243.             for (j=0; j<16; j++)
  1244.                 if (*(src+j/8) & bit[j%8])
  1245.                     *(uint*)(dest+(j/8)*4) |= col_a[j%8];
  1246.         }
  1247.     }
  1248.     else
  1249.     {
  1250.         for (i=0; i<16; i++,dest+=4,src++)
  1251.         {
  1252.             *(uint*)dest = 0;
  1253.             for (j=0; j<8; j++)
  1254.                 if (*src & bit[j])
  1255.                     *(uint*)dest |= col_a[j%8];
  1256.         }
  1257.     }
  1258. }
  1259.  
  1260. static void grp_putchar(int x, int y, int c, int col, int style)
  1261. {
  1262.     char font[16*16/8];
  1263.     para_putBlock par;
  1264.     int xlen,ylen,i;
  1265.     bool kanji;
  1266.     if (c <= 0xff /* 半角文字? */)
  1267.     {
  1268.         kanji = NO;
  1269.         xlen=8, ylen=16;
  1270.         FNT_ankRead(xlen,ylen, c, getds(), font);
  1271.         if (style & FNT_bold)
  1272.         {
  1273.             for (i=0; i<16; i++)
  1274.                 font[i] |= font[i] >> 1;
  1275.         }
  1276.     }
  1277.     else // 全角文字
  1278.     {
  1279.         kanji = YES;
  1280.         xlen=ylen=16;
  1281.         FNT_kanjiRead(xlen,ylen, FNT_sjisToJis(c), getds(), font);
  1282.         if (style & FNT_bold)
  1283.         {
  1284.             for (i=0; i<16; i++)
  1285.             {
  1286.                 unsigned int pat;
  1287.                 pat = (font[i*2] << 8) | font[i*2+1];
  1288.                 pat |= pat >> 1;
  1289.                 font[i*2] = pat >> 8,  font[i*2+1] = pat & 0xff;
  1290.             }
  1291.         }
  1292.     }
  1293.     EGB_writeMode(EGB_work, DrawMATTE);
  1294.     EGB_color(EGB_work,3,0);
  1295. #if 0
  1296.     par.buf = font;
  1297.     par.bufsel = getds();
  1298.     par.x1 = x;
  1299.     par.y1 = y;
  1300.     par.x2 = x + xlen - 1;
  1301.     par.y2 = y + ylen - 1;
  1302.     if (style & FNT_shadow)
  1303.     {
  1304.         EGB_color(EGB_work, 0, Black);
  1305.         par.x1++, par.y1++, par.x2++, par.y2++;
  1306.         EGB_putBlockColor(EGB_work, 0, (char*)&par);
  1307.         par.x1--, par.y1--, par.x2--, par.y2--;
  1308.     }
  1309.     EGB_color(EGB_work, 0, col);
  1310.     EGB_putBlockColor(EGB_work, 0, (char*)&par);
  1311. #else
  1312.     char grpbuf[16*16/2],grpbuf2[16*16/2];
  1313.     grp_putchar_sub(grpbuf,font,kanji,col);
  1314.     if (style & FNT_shadow)
  1315.         grp_putchar_sub(grpbuf2,font,kanji,Black);
  1316.     par.buf = grpbuf;
  1317.     par.bufsel = getds();
  1318.     par.x1 = x;
  1319.     par.y1 = y;
  1320.     par.x2 = x + xlen - 1;
  1321.     par.y2 = y + ylen - 1;
  1322.     if (style & FNT_shadow)
  1323.     {
  1324.         par.buf = grpbuf2;
  1325.         par.x1++, par.y1++, par.x2++, par.y2++;
  1326.         EGB_putBlock(EGB_work, 0, (char*)&par);
  1327.         par.x1--, par.y1--, par.x2--, par.y2--;
  1328.         par.buf = grpbuf;
  1329.     }
  1330.     EGB_putBlock(EGB_work, 0, (char*)&par);
  1331. #endif
  1332. }
  1333.  
  1334. #endif
  1335.  
  1336.  
  1337. void    ART_putstr_style(int x, int y, char *str, int col, int style)
  1338. {
  1339. #if 1
  1340.     EGB_fontStyle(EGB_work, style);
  1341.     EGB_color(EGB_work, 1, Black);
  1342.     grp_putstr(x,y,str,col);
  1343. #else
  1344.     int c;
  1345.     for (;;)
  1346.     {
  1347.         if (*str == 0)
  1348.             break;
  1349.         if (iskanji(*str))
  1350.         {
  1351.             c = *str * 256 + *(str+1);
  1352.             grp_putchar(x,y,c,col,style);
  1353.             str++,str++;
  1354.             x += 16;
  1355.         }
  1356.         else
  1357.         {
  1358.             c = *str;
  1359.             grp_putchar(x,y,c,col,style);
  1360.             str++;
  1361.             x += 8;
  1362.         }
  1363.     }
  1364. #endif
  1365. }
  1366.  
  1367.  
  1368. void    ART_putstr(int x, int y, char *str, int col)
  1369. {
  1370.     ART_putstr_style(x,y,str,col,0);
  1371. }
  1372.  
  1373.  
  1374. void ARTputstr12(int x,int y, char *str, int forecol, int backcol)
  1375. {
  1376.     #define    PUTBITBLOCK(x1,y1,x2,y2,dat) { \
  1377.         char para[16];   DWORD(para)=(unsigned int)dat; WORD(para+4)=getds(); \
  1378.         WORD(para+6)=x1; WORD(para+8)=y1; WORD(para+10)=x2; WORD(para+12)=y2; \
  1379.         EGB_putBlockColor(EGB_work, 0, para); }
  1380.     int ds = getds();
  1381.     char fontbuf[24];
  1382.     EGB_color(EGB_work, 0, forecol);
  1383.     EGB_writeMode(EGB_work, DrawNORMAL);
  1384.     while (*str != 0)
  1385.     {
  1386.         if (*str == '\a')
  1387.         {
  1388.             putpict(x,y,Partemis);
  1389.             while (*str == '\a')  str++;
  1390.             x += 52;
  1391.         }
  1392.         else if (_iskanji(*str))
  1393.         {
  1394.             int ofs, sjis = (*str)*256 + *(str+1), jis;
  1395.             jis = FNT_sjisToJis(sjis);
  1396.             if (_iskanji1(sjis))
  1397.             {
  1398.                 ofs = ( ((jis>>8)-0x21)*94 + (jis&0xff) - 0x21)*24 + 0xc00;
  1399.                 _movedata(font12seg, ofs, ds, (uint)fontbuf, 24);
  1400.             }
  1401.             else    // 第1水準じゃない場合
  1402.             {
  1403.                 char font16buf[32];
  1404.                 FNT_kanjiRead(16,16,jis,ds,font16buf);
  1405.                 memset(fontbuf,0,24);
  1406.                 int di=0;
  1407.                 for (int i=0; i<16; i++)
  1408.                 {
  1409.                     ushort p;
  1410.                     p = ((ushort)font16buf[i*2]<<8) | font16buf[i*2+1];
  1411.                     p =  (p&0xc000) | ((p&0x3c00)<<1) | ((p&0x3c0)<<2) |
  1412.                         ((p&0x3c)<<3) | ((p&0x3)<<4);
  1413.                     fontbuf[di*2]   |= (p>>8) & 0xff;
  1414.                     fontbuf[di*2+1] |= p & 0xff;
  1415.                     if (i!=1 && i!=4 && i!=7 && i!=10)
  1416.                         di++;
  1417.                 }
  1418.             }
  1419.             PUTBITBLOCK(x,y,x+11,y+11,fontbuf);
  1420.             str++,str++;
  1421.             x += 12;
  1422.         }
  1423.         else
  1424.         {
  1425.             if (*str != ' ')
  1426.             {
  1427.                 int ofs = (int)*str * 12;
  1428.                 _movedata(font12seg, ofs, ds, (uint)fontbuf, 12);
  1429.                 PUTBITBLOCK(x,y,x+5,y+11,fontbuf);
  1430.             }
  1431.             str++;
  1432.             x += 6;
  1433.         }
  1434.     }
  1435. }
  1436.  
  1437.  
  1438. /* end of subgrp.c */
  1439.